iT邦幫忙

2021 iThome 鐵人賽

DAY 6
0

對於請求的處理如果都寫在路由器內那就太擠了,再 Laravel 中判定路由後都會將請求傳遞到控制器進行對應。

建立基本控制器

可以用指令建立控制器

sail artisan make:controller <ContorllerName>

建立好的控制器預設放在 App\Http\Controllers 資料夾中,並且 namespace 也是。

建好的空控制器

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    //
}

在這當中定義處理函式,跟前面路由器的 Callback 定義方式相同,可以帶上依賴注入的 Requeset 實例跟路徑參數,或是跟 Model 進行綁定

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
     /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Photo  $photo
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Photo $photo)
    {
        //
    }
}

串接路由與控制器

在路由器中引入控制器,並指定控制器中的方法給指定路由

// api.php
use App\Http\Controllers\UserController;

Route::get('/user/{id}', [UserController::class, 'show']);

加上 Middleware

可以在路由器中加上 Middleware

Route::get('profile', [UserController::class, 'show'])->middleware('auth');

也可以加在控制器中,這樣經由這個控制器處理的請求都會先經過 Middleware 處理

class UserController extends Controller
{
    /**
     * Instantiate a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('log')->only('index');
        $this->middleware('subscribed')->except('store');
    }
}

Resource 路由與控制器

通常一個控制器都是針對某一個 Model 進行處理,像是 UserController 負責處理 User 的 CRUD ,而因為對各 Model 的這類處理都大同小異, Laravel 就預設了快捷的 API 的定義方式

//web.php
Route::resource('photos', PhotoController::class);

Route::resource 當中包含了一組完整的CRUD 路由定義,而每個路由對應到控制器中的方法名稱也都指定好了,對照表如下:

請求方法 路由 控制器函式 路由名稱標籤
GET /photos index photos.index
GET /photos/create create photos.create
POST /photos store photos.store
GET /photos/{photo} show photos.show
GET /photos/{photo}/edit edit photos.edit
PUT/PATCH /photos/{photo} update photos.update
DELETE /photos/{photo} destroy photos.destroy

{photo} 的部分通常是帶入主鍵 Id 的值,用來查詢單筆資料,對應的方法也都是用來處理單筆資料的。

Route::resource 主要是用來處理瀏覽器端(web.php)的請求,所以會包含要求建立/編輯表單畫面的 create/edit 路由。

而像是手機 App 來的請求不會用到 create/edit ,因為 App 都內建畫面了,所以也有另外的方法對應這方面的 api

// api.php
use App\Http\Controllers\PhotoController;

Route::apiResource('photos', PhotoController::class);

如上所述, apiResource 跟 resource 路由相比只是少了 create/edit 方法。

如果 resource 中有不需要的路由或是只需要其中幾個路由,可以再加定義

use App\Http\Controllers\PhotoController;

// 剔除不需要的路由
Route::resource('photos', PhotoController::class)->except([
    'create', 'store', 'update', 'destroy'
]);

// 只取需要的路由
Route::resource('photos', PhotoController::class)->only([
    'index', 'show'
]);

指令產生 resource 控制器

Laravel 提供了快捷的指令產生可以對應 resource 路由的控制器

sail artisan make:controller PhotoController --resource

這樣生成的控制器中會先生成 index/create 等對應 Route::resource 的空函式,也會定義好預設的參數,以 show 為例

/**
 * Display the specified resource.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function show($id)
{
    //
}

會先定義好路徑參數為 $id。

如果想略過用 $id 查詢資料的步驟,可以直接建立與 Model 連結的控制器

sail artisan make:controller PhotoController --resource --model=Photo

指定了 Model 的話,參數會直接變成該 Model 的型別,根據上一篇路由綁定 Model 的說明,就可以直接取出該 id 對應的資料進行處理

/**
 * Display the specified resource.
 *
 * @param  \App\Models\Photo  $photo
 * @return \Illuminate\Http\Response
 */
public function show(Photo $photo)
{
    //
}

指令產生 apiResource 控制器

產生對應 apiResource 的控制器,只是少了 create/edit 方法,其他都跟 resource 指令的結果相同

sail artisan make:controller PhotoController --api

References

Laravel Controller

上一篇
Router
下一篇
資料庫連線設定
系列文
Laravel 實務筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言